package com.zmn.oms.zmn.business.impl.work.customwork;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.zmn.base.channel.common.dro.ChannelDRO;
import com.zmn.base.channel.dubbo.interfaces.channel.ChannelListRemoteService;
import com.zmn.base.common.data.common.dro.area.AreaDRO;
import com.zmn.base.common.data.dubbo.interfaces.area.AreaListRemoteService;
import com.zmn.base.engineer.common.constants.DubboConsts;
import com.zmn.base.engineer.common.dro.foreign.engineer.ForeignEngineerBasicInfoDRO;
import com.zmn.base.engineer.common.dro.foreign.engineer.ForeignEngineerDetailInfoDRO;
import com.zmn.base.engineer.dubbo.interfaces.foreign.EngineerListRemoteService;
import com.zmn.base.price.common.dto.ProductPriceDRO;
import com.zmn.base.price.common.dto.ProductPriceQuery;
import com.zmn.base.price.dubbo.interfaces.calculate.ProductPriceRemoteService;
import com.zmn.base.price.dubbo.interfaces.calculate.ProductTariffRemoteService;
import com.zmn.base.sdss.common.model.dio.oms.EngineerProductGroupCompositeScoreForDispatchOrderDIO;
import com.zmn.base.sdss.common.model.dro.oms.EngineerProductGroupCompositeScoreForDispatchOrderDRO;
import com.zmn.base.sdss.dubbo.interfaces.oms.CompositeServeScoreForOmsListRemoteService;
import com.zmn.coa.common.consts.CommonConsts;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.map.Point;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.reflect.BeanMapper;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.consts.GlobalConsts;
import com.zmn.manager.mq.interfaces.ZmnMQSender;
import com.zmn.manager.redis.RedisManager;
import com.zmn.oms.business.interfaces.baidumap.BaiduMapBService;
import com.zmn.oms.business.interfaces.changerecord.OrderChangeRecordBService;
import com.zmn.oms.business.interfaces.master.OrderMasterBService;
import com.zmn.oms.business.interfaces.masternotice.MasterNoticeHistoryBService;
import com.zmn.oms.business.interfaces.messageV1.app.MessageSendAppService;
import com.zmn.oms.business.interfaces.mq.MqProviderService;
import com.zmn.oms.business.interfaces.orderamount.OrderAmountCalcBService;
import com.zmn.oms.business.interfaces.orderstock.OrderStockBService;
import com.zmn.oms.business.interfaces.part.OrderPartBService;
import com.zmn.oms.business.interfaces.remark.OrderRemarkBService;
import com.zmn.oms.business.interfaces.serviceitem.OrderServiceItemBService;
import com.zmn.oms.business.interfaces.servtype.ServItemBService;
import com.zmn.oms.business.interfaces.work.OrderWorkAmountBService;
import com.zmn.oms.business.interfaces.work.customwork.CustomWorkBService;
import com.zmn.oms.business.interfaces.xno.OrderXnoBindBService;
import com.zmn.oms.business.interfaces.xno.OrderXnoBindService;
import com.zmn.oms.common.annotation.OrderWorkCasOperate;
import com.zmn.oms.common.annotation.ZsNormalOrderWorkLog;
import com.zmn.oms.common.constant.*;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.constant.MessageQueueTopicConstant;
import com.zmn.oms.model.bo.orderamount.OrderAmountCalcBO;
import com.zmn.oms.model.bo.orderamount.ReCalcOrderAmountDIO;
import com.zmn.oms.model.dio.part.OrderPartReviewDIO;
import com.zmn.oms.model.dto.changerecord.ChangeLiableMasterDTO;
import com.zmn.oms.model.dto.master.MultiMasterDTO;
import com.zmn.oms.model.dto.order.OrderDTO;
import com.zmn.oms.model.dto.orderstock.LockStockDTO;
import com.zmn.oms.model.dto.orderstock.ReleaseStockDTO;
import com.zmn.oms.model.dto.remark.OrderRemarkDTO;
import com.zmn.oms.model.dto.remark.OrderRemarkDetailDTO;
import com.zmn.oms.model.dto.work.distribute.ERPEngineerDRO;
import com.zmn.oms.model.dto.work.distribute.ERPMessageDRO;
import com.zmn.oms.model.dto.work.masterwork.ModifyProductDTO;
import com.zmn.oms.model.dto.work.modify.*;
import com.zmn.oms.model.dto.work.modify.must.OrderAssignDTO;
import com.zmn.oms.model.dto.work.xno.XnoBindDTO;
import com.zmn.oms.model.dto.work.xno.XnoUnBindDTO;
import com.zmn.oms.model.entity.changerecord.OrderChangeRecord;
import com.zmn.oms.model.entity.detail.OrderDetail;
import com.zmn.oms.model.entity.master.OrderMaster;
import com.zmn.oms.model.entity.masterworking.MasterWorking;
import com.zmn.oms.model.entity.order.OrderExtend;
import com.zmn.oms.model.entity.orderattachment.OrderAttachment;
import com.zmn.oms.model.entity.product.OrderProduct;
import com.zmn.oms.model.entity.visit.OrderVisit;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.services.interfaces.acceptance.OrderWorkAcceptanceService;
import com.zmn.oms.services.interfaces.changerecord.OrderChangeRecordService;
import com.zmn.oms.services.interfaces.detail.OrderDetailService;
import com.zmn.oms.services.interfaces.master.OrderMasterService;
import com.zmn.oms.services.interfaces.masterworking.MasterWorkingService;
import com.zmn.oms.services.interfaces.order.OrderExtendService;
import com.zmn.oms.services.interfaces.orderattachment.OrderAttachmentService;
import com.zmn.oms.services.interfaces.product.OrderProductExtendService;
import com.zmn.oms.services.interfaces.product.OrderProductService;
import com.zmn.oms.services.interfaces.serviceitem.OrderServiceItemService;
import com.zmn.oms.services.interfaces.tag.OrderTagService;
import com.zmn.oms.services.interfaces.visit.OrderVisitService;
import com.zmn.oms.services.interfaces.wallquotation.WallQuotationService;
import com.zmn.oms.services.interfaces.wallservitem.WallServItemService;
import com.zmn.oms.services.interfaces.warranty.OrderWarrantyService;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import com.zmn.oms.services.interfaces.work.masterwork.MasterWorkService;
import com.zmn.oms.zmn.business.interfaces.part.ZsOrderFactoryPartBService;
import com.zmn.oms.zmn.business.interfaces.quotation3.OrderQuotation3ModifyBService;
import com.zmn.oms.zmn.business.interfaces.work.OrderWorkAssignBService;
import com.zmn.oms.zmn.business.interfaces.work.OrderWorkModifyProductBService;
import com.zmn.oms.zmn.business.interfaces.work.OrderWorkMultipleVisitBService;
import com.zmn.oms.zmn.business.interfaces.work.ZsOrderWorkBService;
import com.zmn.oms.zmn.business.interfaces.work.customwork.ZsCustomWorkBService;
import com.zmn.oms.zmn.normal.business.interfaces.part.ZsNormalOrderPartBService;
import com.zmn.pay.common.constant.PayConsts;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 类描述：客服工单业务实现
 *
 * @author liuying
 * @date 2018/11/02 21:02
 */
@Slf4j
@Service
public class ZsCustomWorkBServiceImpl implements ZsCustomWorkBService {

    @DubboReference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION , check = false)
    private ChannelListRemoteService channelListRemoteService;

    @Autowired
    private MqProviderService mqProviderService;

    @DubboReference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION , check = false)
    private AreaListRemoteService areaListRemoteService;

    @DubboReference(version = DubboConsts.INTERFACE_VERSION, check = false)
    private EngineerListRemoteService engineerListRemoteService;

    @DubboReference(version = com.zmn.base.engineer.common.constants.DubboConsts.INTERFACE_VERSION, check = false)
    private ProductPriceRemoteService productPriceRemoteService;
    @DubboReference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION , check = false)
    private ProductTariffRemoteService productTariffRemoteService;
    @DubboReference(version = com.zmn.base.sdss.dubbo.interfaces.consts.DubboConsts.INTERFACE_VERSION, check = false)
    private CompositeServeScoreForOmsListRemoteService compositeServeScoreForOmsListRemoteService;

    @Autowired
    private OrderDetailService orderDetailService;
    @Autowired
    private CustomWorkBService customWorkBService;
    @Autowired
    private OrderWorkService orderWorkService;
    @Autowired
    private OrderMasterService orderMasterService;
    @Autowired
    private OrderMasterBService orderMasterBService;
    @Autowired
    private OrderPartBService orderPartBService;
    @Autowired
    private OrderExtendService orderExtendService;
    @Autowired
    private OrderAttachmentService orderAttachmentService;
    @Autowired
    private OrderWarrantyService orderWarrantyService;
    @Autowired
    private OrderServiceItemService orderServiceItemService;
    @Autowired
    private OrderProductExtendService orderProductExtendService;
    @Autowired
    private MasterWorkingService masterWorkingService;
    @Autowired
    private ZsOrderFactoryPartBService zsOrderFactoryPartBService;
    @Autowired
    private OrderWorkAmountBService orderWorkAmountBService;
    @Autowired
    private OrderWorkModifyProductBService orderWorkModifyProductBService;
    @Autowired
    private OrderProductService orderProductService;
    @Autowired
    private MasterWorkService masterWorkService;
    @Autowired
    protected OrderAmountCalcBService orderAmountCalcBService;
    @Autowired
    OrderXnoBindService orderXnoBindService;
    @Autowired
    OrderXnoBindBService orderXnoBindBService;
    @Resource
    private RedisManager redisManager;
    @Autowired
    private ZsOrderWorkBService zsOrderWorkBService;
    @Autowired
    private MessageSendAppService messageSendAppService;
    @Autowired
    private ZmnMQSender zmnMQSender;
    @Autowired
    private OrderWorkAssignBService orderWorkAssignBService;
    @Autowired
    private BaiduMapBService baiduMapBService;
    @Autowired
    OrderStockBService orderStockBService;
    @Autowired
    private OrderWorkAcceptanceService orderWorkAcceptanceService;
    @Resource
    private OrderChangeRecordBService orderChangeRecordBService;
    @Resource
    private OrderChangeRecordService orderChangeRecordService;
    @Resource
    private OrderRemarkBService orderRemarkBService;
    @Autowired
    private OrderWorkMultipleVisitBService orderWorkMultipleVisitBService;
    @Autowired
    private OrderVisitService orderVisitService;
    @Autowired
    private ServItemBService servItemBService;
    @Autowired
    private OrderQuotation3ModifyBService orderQuotation3ModifyBService;
    @Autowired
    private ZsNormalOrderPartBService zsNormalOrderPartBService;
    @Autowired
    OrderServiceItemBService orderServiceItemBService;
    @Autowired
    private OrderTagService orderTagService;

    @Resource
    private WallServItemService wallServItemService;

    @Resource
    private WallQuotationService wallQuotationService;

    @Resource
    private MasterNoticeHistoryBService masterNoticeHistoryBService;

    /**
     * 财务配置快照-派单
     */
    public static final String MQ_CONFIG_SNAPSHOT_DISTRIBUTE_TAG = "MQ_CONFIG_SNAPSHOT_DISTRIBUTE_TAG";

    protected Logger logger = LoggerFactory.getLogger(this.getClass());

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    // 删除自动派单存根
    private void delAutoDistributeStub(Long workId) {
        String key = String.format(RedisKeyConsts.WAIT_AUTO_DISTRIBUTE_ORDER, workId);
        redisManager.del(key);
    }

    @Override
    public void updateOrderMultiMasterByOrderId(Long orderId, Long workId, Integer dbMultiMaster) {
        // 更新工单多工程师状态
        List<OrderMaster> orderSlaveMasterList = orderMasterService.listMasterByWorkId(orderId, workId, OrderConsts.ORDER_MASTER_TYPE_SLAVE);
        int multiMaster = CollectionUtils.isEmpty(orderSlaveMasterList) ? GlobalConsts.NO : GlobalConsts.YES;
        if (!Objects.equals(multiMaster, dbMultiMaster)) {
            OrderWork orderWork = new OrderWork();
            orderWork.setOrderId(orderId);
            orderWork.setWorkId(workId);
            orderWork.setMultiMaster(multiMaster);
            orderWork.setUpdater(com.zmn.common.constant.GlobalConsts.getOperatorTypeName(com.zmn.common.constant.GlobalConsts.OPERATE_USER_TYPE_SYSTEM));
            orderWork.setUpdateTime(DateUtil.getNow());
            orderWorkService.saveMultiMaster(orderWork);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @OrderWorkCasOperate(type = OrderConsts.ORDER_OP_TYPE_DISTRIBUTE)
    @ZsNormalOrderWorkLog(type = OrderLogConsts.ORDER_LOG_TYPE_DISTRIBUTE, beforeProceed = false)
    public boolean saveDistribute(OrderDistributeDTO distributeDTO) throws OmsBaseException {
        return this.saveDistributeImpl(distributeDTO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @OrderWorkCasOperate(type = OrderConsts.ORDER_OP_TYPE_DISTRIBUTE_NEW)
    @ZsNormalOrderWorkLog(type = OrderLogConsts.ORDER_LOG_TYPE_DISTRIBUTE, beforeProceed = false)
    public boolean saveNewDistribute(OrderDistributeDTO distributeDTO) throws OmsBaseException {
        OrderWork dbOrderWork = orderWorkService.findOrderWorkByKey(distributeDTO.getOrderId(), distributeDTO.getWorkId());

        // 改派逻辑 继承之前的
        boolean result = this.saveDistributeImpl(distributeDTO);

        OrderChangeRecord orderChangeRecord = orderChangeRecordService.getChangeRecordByOrderId(distributeDTO.getOrderId());

        // 是否是非首次派单
        Boolean nonFirstDistribute = Objects.equals(OrderDistributeConsts.DISTRIBUTE_ENTRY_ADMIN, distributeDTO.getDistributeEntry())
                && StringUtils.isNotBlank(orderChangeRecord.getFirstDistributeOptName());
        if (result && nonFirstDistribute) {
            // 记录当天服务商改派次数
            recordServiceCompanyRedistributeCount(dbOrderWork.getManageCompanyId());
        }

        return result;
    }

    private void recordServiceCompanyRedistributeCount(Integer manageCompanyId) {

        String redisKey = String.format(RedisKeyConsts.ORDER_SERVICE_COMPANY_REDISTRIBUTE_COUNT_DAY_KEY, manageCompanyId);

        if (!redisManager.exists(redisKey)) {
            // 离散该数据，推迟至第二天12点后的5分钟内，防止大量过期导致redis阻塞
            redisManager.incr(redisKey);

            // 第二天 00:00:00 的时间，单位：秒
            Date tomorrow = DateUtil.getDateStart(DateUtil.addDays(DateUtil.getNow(), 1));
            long toTomorrowSec = (tomorrow.getTime() - DateUtil.getNowTimestampMillis()) / 1000;

            // 偏移量
            int offset = new Random().nextInt(DateUtil.SECOND_OF_5MINUTES);

            redisManager.expire(redisKey, ((Long) (toTomorrowSec + offset)).intValue());
        } else {
            redisManager.incr(redisKey);
        }
    }

    public boolean saveDistributeImpl(OrderDistributeDTO distributeDTO) throws OmsBaseException {

        logger.info("[{}]保存派单参数：【{}】", distributeDTO.getOrderId(), JSON.toJSONString(distributeDTO));

        // 如果是人工派单网格外工程师
        if (Objects.equals(distributeDTO.getDistributeGrid(), OrderDistributeConsts.DISTRIBUTE_GRID_OUT)
                && !distributeDTO.isAutoDistribute()) {
            String acrossRedisKey = String.format(RedisKeyConsts.ACROSS_DISTRIBUTE_WAIT_TIME_ORDER, distributeDTO.getWorkId());
            String acrossRedisValue = redisManager.get(acrossRedisKey);
            // 如果该订单正在等待跨网格时长，手动派单不能派单给网格外工程师
            if (StringUtil.isNotBlank(acrossRedisValue)) {
                throw new OmsBaseException("跨网格派等待订单，不能进行人工网格外派单！");
            }
        }

        // 设置派单时间
        distributeDTO.setDistributeDate(Optional.ofNullable(distributeDTO.getOperateTime()).orElse(DateUtil.getNow()));

        // 删除自动派单存根
        this.delAutoDistributeStub(distributeDTO.getWorkId());

        OrderWork dbOrderWork = orderWorkService.findOrderWorkByKeySrcMaster(distributeDTO.getOrderId(), distributeDTO.getWorkId());
        OrderDetail orderDetail = orderDetailService.findOrderDetailByKeySrcMaster(dbOrderWork.getOrderId());

        // 原工程师
        Integer originalMasterId = dbOrderWork.getMasterId();
        if (NumberUtil.isNullOrZero(distributeDTO.getOriginalMasterId()) && NumberUtil.isNotNullOrZero(originalMasterId)) {
            distributeDTO.setOriginalMasterId(originalMasterId);
        }

        // 不是进行中的工单不处理
        if (dbOrderWork == null || dbOrderWork.getResultStatus() != OrderStatusConsts.WORK_RESULT_DOING) {
            return false;
        }

        // 自动派单不是已确认状态或者已分单状态，不自动派单
        if (distributeDTO.isAutoDistribute()) {
            if (!Objects.equals(dbOrderWork.getStatus(), OrderStatusConsts.WORK_STATUS_CONFIRM) &&
                    !Objects.equals(dbOrderWork.getStatus(), OrderStatusConsts.WORK_STATUS_ASSIGN)) {
                return false;
            }
        }

        // 上门之后的状态不处理
        if (dbOrderWork.getStatus() > OrderStatusConsts.WORK_STATUS_VISIT) {
            return false;
        }

        // 如果工程师未变，并且状态是已派单的 不作处理
        if (Objects.equals(dbOrderWork.getMasterId(), distributeDTO.getMasterId()) && dbOrderWork.getStatus() >= OrderStatusConsts.WORK_STATUS_DISTRIBUTE) {
            throw new OmsBaseException("不可再次派单给同一个工程师");
        }

        // 已派单的，撤回重新操作
        boolean cleanOrderData = dbOrderWork.getMasterId() != null &&
                (Objects.equals(dbOrderWork.getStatus(), OrderStatusConsts.WORK_STATUS_TAKE)
                        || Objects.equals(dbOrderWork.getStatus(), OrderStatusConsts.WORK_STATUS_DISTRIBUTE)
                        || Objects.equals(dbOrderWork.getStatus(), OrderStatusConsts.WORK_STATUS_VISIT));
        if (cleanOrderData) {
            OrderUpdateStatusDTO orderUpdateStatusDTO = new OrderUpdateStatusDTO();
            orderUpdateStatusDTO.setWorkId(distributeDTO.getWorkId());
            orderUpdateStatusDTO.setOrderId(distributeDTO.getOrderId());
            orderUpdateStatusDTO.setStatus(OrderStatusConsts.WORK_STATUS_ASSIGN);
            orderUpdateStatusDTO.setOperatorId(distributeDTO.getOperatorId());
            orderUpdateStatusDTO.setOperator(distributeDTO.getOperator());
            this.updateToAssignStatus(orderUpdateStatusDTO, dbOrderWork);

            // 清空个人形象照片数据
            OrderExtend orderExtend = new OrderExtend();
            orderExtend.setExtId(distributeDTO.getOrderId());
            orderExtend.setMasterSrc("");
            // 计价器3.0订单需要清空微信扫码用户
            if (Objects.equals(dbOrderWork.getServItemType(), OrderConsts.SERVICE_ITEM_TYPE_QUOTATION_THREE)) {
                orderExtend.setWeChatScanUserId(0L);
            }

            orderExtendService.clearDistributeInfo(orderExtend);

            // 清空渠道附件
            orderAttachmentService.deleteByOrderId(distributeDTO.getOrderId());

            // 清空墙面报价数据
            wallQuotationService.deleteByKey(distributeDTO.getWorkId());
            wallServItemService.deleteByWorkId(distributeDTO.getWorkId());

            // 计价器3.0订单需要清空上门信息
            if (Objects.equals(dbOrderWork.getServItemType(), OrderConsts.SERVICE_ITEM_TYPE_QUOTATION_THREE)) {
                orderChangeRecordService.clearVisitInfo(distributeDTO.getOrderId(), distributeDTO.getWorkId());
            }
        }

        // 工程师基本信息
        ForeignEngineerBasicInfoDRO masterBasicInfoDRO = null;
        distributeDTO.setCompanyId(dbOrderWork.getCompanyId());
        // 网格化派单保存分单信息
        if (Objects.equals(distributeDTO.getDistributeWay(), OrderDistributeConsts.DISTRIBUTE_WAY_PLAT)) {
            logger.info("saveDistributeImpl#getEngineerById 入参 [{}]",distributeDTO.getMasterId());
            ResponseDTO<ForeignEngineerBasicInfoDRO> responseDTO = engineerListRemoteService.getEngineerById(distributeDTO.getMasterId());
            logger.info("saveDistributeImpl#getEngineerById 出参 [{}]",JSON.toJSONString(responseDTO));
            if (responseDTO.isSuccess() && Objects.nonNull(responseDTO.getData())) {
                masterBasicInfoDRO = responseDTO.getData();
                OrderAssignDTO orderAssignDTO = new OrderAssignDTO();
                orderAssignDTO.setOrderId(distributeDTO.getOrderId());
                orderAssignDTO.setWorkId(distributeDTO.getWorkId());
                orderAssignDTO.setOperatorId(distributeDTO.getOperatorId());
                orderAssignDTO.setAssignDate(distributeDTO.getDistributeDate());
                orderAssignDTO.setCompanyId(masterBasicInfoDRO.getSubCompanyId());
                orderAssignDTO.setManageCompanyId(masterBasicInfoDRO.getSpCompanyId());
                orderWorkAssignBService.saveAssignEventNoLog(orderAssignDTO);
                distributeDTO.setCompanyId(masterBasicInfoDRO.getSubCompanyId());

                // 无网格抢单更新行政信息
                if (Objects.equals(distributeDTO.getGrabWay(), GlobalConsts.YES)) {
                    OrderDetail updateDetail = new OrderDetail();
                    updateDetail.setDetailId(distributeDTO.getOrderId());
                    updateDetail.setGridCompanyId(masterBasicInfoDRO.getSubCompanyId());
                    updateDetail.setGridCompanyName(masterBasicInfoDRO.getSubCompanyName());
                    updateDetail.setGridManageCompanyId(masterBasicInfoDRO.getSpCompanyId());
                    updateDetail.setGridManageCompanyName(masterBasicInfoDRO.getSpCompanyName());
                    updateDetail.setUpdater(distributeDTO.getOperator());
                    orderDetailService.updateOrderDetailByKey(updateDetail);
                }

                //记录分单日志
                distributeDTO.setCompanyName(masterBasicInfoDRO.getSubCompanyName());
                distributeDTO.setManageCompanyName(masterBasicInfoDRO.getSpCompanyName());

                // 记录网格信息日志
                OrderDetail dbOrderDetail = orderDetailService.findOrderDetailByKey(distributeDTO.getOrderId());
                distributeDTO.setGridId(dbOrderDetail.getGridId());
                distributeDTO.setGridName(dbOrderDetail.getGridName());
            }
        }

        // 改派发送撤回app消息
        if (!Objects.equals(dbOrderWork.getMasterId(), distributeDTO.getMasterId())) {
            Map<String, Object> params = Maps.newHashMap();
            params.put("order_id", String.valueOf(dbOrderWork.getOrderId()));
            params.put("work_id", String.valueOf(dbOrderWork.getWorkId()));
            messageSendAppService.pushAppMessageInfo(MessageConsts.ZMN_MSG_RULEID_BACK, JSON.toJSONString(params), dbOrderWork);
        }

        // 工程师有变化，解绑小号
        if (!Objects.equals(dbOrderWork.getMasterId(), GlobalConsts.NONE)
                && !Objects.equals(dbOrderWork.getMasterId(), distributeDTO.getMasterId())
                && Objects.equals(orderDetail.getBindStatus(), OrderConsts.BIND_STATUS_BIND)) {
            XnoUnBindDTO xnoUnBindDTO = new XnoUnBindDTO();
            xnoUnBindDTO.setUnBindMasterId(dbOrderWork.getMasterId());
            xnoUnBindDTO.setWorkId(dbOrderWork.getWorkId());
            xnoUnBindDTO.setOrderId(dbOrderWork.getOrderId());
            xnoUnBindDTO.setOperatorLogRemark("[改派解绑小号]");
            xnoUnBindDTO.setOperateTime(new Date(distributeDTO.getDistributeDate().getTime() - 1));
            orderXnoBindBService.unBind(xnoUnBindDTO);
        }

        Integer newServiceItemType = dbOrderWork.getServItemType();
        Integer newFinalPrice = dbOrderWork.getFinalPrice();
        // 派单给家修匠才重新判断服务类型
        if (Objects.equals(distributeDTO.getCompanyId(), CompanyConsts.ZMN_JXJ_COMPANY_ID)) {
            // 重新判断工单类型
            CheckQuotationTypeOrderDTO checkQuotationTypeOrderDTO = BeanMapper.map(dbOrderWork, CheckQuotationTypeOrderDTO.class);
            checkQuotationTypeOrderDTO.setCompanyId(distributeDTO.getCompanyId());
            checkQuotationTypeOrderDTO.setMasterId(distributeDTO.getMasterId());
            checkQuotationTypeOrderDTO.setCompatibilityFinalPrice(true);
            newServiceItemType = servItemBService.getServItemType(checkQuotationTypeOrderDTO);
            // servItemType==5的修改成4，并且标识一口价（一口价订单需求兼容app走计价器3.0流程）
            if (Objects.equals(newServiceItemType, OrderConsts.SERVICE_ITEM_TYPE_FINAL_PRICE)) {
                distributeDTO.setServItemType(OrderConsts.SERVICE_ITEM_TYPE_QUOTATION_THREE);
                distributeDTO.setFinalPrice(GlobalConsts.YES);
                newServiceItemType = OrderConsts.SERVICE_ITEM_TYPE_QUOTATION_THREE;
                newFinalPrice = GlobalConsts.YES;
            }else {
                distributeDTO.setFinalPrice(GlobalConsts.NO);
                distributeDTO.setServItemType(newServiceItemType);
                newFinalPrice = GlobalConsts.NO;
            }
            log.info("[{}]修改计价类型，旧类型[{},{}]-->新类型[{},{}]", dbOrderWork.getWorkId(), dbOrderWork.getServItemType(), dbOrderWork.getFinalPrice(), newServiceItemType, newFinalPrice);
        }

        // 保存派单结果
        distributeDTO.setDbOrderWork(dbOrderWork);
        customWorkBService.saveDistribute(distributeDTO);

        // 工程师有变化，重新绑定小号
        if (!Objects.equals(dbOrderWork.getMasterId(), distributeDTO.getMasterId())) {
            XnoBindDTO xnoBindDTO = new XnoBindDTO();
            xnoBindDTO.setOrderId(distributeDTO.getOrderId());
            xnoBindDTO.setWorkId(distributeDTO.getWorkId());
            xnoBindDTO.setOperatorLogRemark("[派单绑定小号]");
            xnoBindDTO.setOperateTime(new Date(distributeDTO.getDistributeDate().getTime() + 1));
            orderXnoBindBService.bind(xnoBindDTO);
        }

        // 处理关联多师傅（学徒）
        this.processRelateMultiMaster(distributeDTO, dbOrderWork, masterBasicInfoDRO);

        // 更新工单多工程师状态
        List<OrderMaster> orderSlaveMasterList = orderMasterService.listMasterByWorkIdSrcMaster(dbOrderWork.getOrderId(), dbOrderWork.getWorkId(), OrderConsts.ORDER_MASTER_TYPE_SLAVE);
        OrderWork orderWork = new OrderWork();
        orderWork.setOrderId(dbOrderWork.getOrderId());
        orderWork.setWorkId(dbOrderWork.getWorkId());
        orderWork.setMultiMaster(CollectionUtils.isEmpty(orderSlaveMasterList) ? GlobalConsts.NO : GlobalConsts.YES);
        orderWork.setUpdater(distributeDTO.getOperator());
        orderWork.setUpdateTime(DateUtil.getNow());
        orderWorkService.saveMultiMaster(orderWork);

        // 修改师傅出发状态
        OrderWork updateMasterLeaveOrderWork = new OrderWork();
        updateMasterLeaveOrderWork.setOrderId(dbOrderWork.getOrderId());
        updateMasterLeaveOrderWork.setWorkId(dbOrderWork.getWorkId());
        updateMasterLeaveOrderWork.setIsLeave(GlobalConsts.NO);  //1未出发  2已出发
        masterWorkService.updateMasterLeave(updateMasterLeaveOrderWork);

        // 设置接单时间
        OrderWork updateOrderWork = new OrderWork();
        updateOrderWork.setWorkId(distributeDTO.getWorkId());
        updateOrderWork.setOrderId(distributeDTO.getOrderId());
        updateOrderWork.setAssignConfirmerId(distributeDTO.getOperatorId());
        updateOrderWork.setAssignConfirmTime(DateUtil.getNow());
        orderWorkService.updateOrderWorkAssignConfirm(updateOrderWork);

        // 保存进行中的工单
        Integer oldMasterId = dbOrderWork.getMasterId();
        dbOrderWork.setMasterId(distributeDTO.getMasterId());
        this.saveMasterWorking(dbOrderWork, OrderStatusConsts.WORK_STATUS_DISTRIBUTE, newServiceItemType, newFinalPrice);
        // 保存责任工程师 2020/04/12 返修单改派，不受改派缘由定义的责任归属影响 责任归属
        if (!Objects.equals(OrderConsts.ORDER_TYPE_REWORK, dbOrderWork.getType())) {
            ChangeLiableMasterDTO changeLiableMasterDTO = new ChangeLiableMasterDTO();
            changeLiableMasterDTO.setOrderId(distributeDTO.getOrderId());
            changeLiableMasterDTO.setMasterId(distributeDTO.getMasterId());
            changeLiableMasterDTO.setMasterName(distributeDTO.getMasterName());
            changeLiableMasterDTO.setLiableType(distributeDTO.getLiableType());
            orderChangeRecordBService.updateLiableMasterRecord(changeLiableMasterDTO);
            // 保存取消责任工程师
            ChangeLiableMasterDTO cancelLiableMasterDTO = new ChangeLiableMasterDTO();
            cancelLiableMasterDTO.setOrderId(distributeDTO.getOrderId());
            cancelLiableMasterDTO.setLiableMasterId(distributeDTO.getMasterId());
            cancelLiableMasterDTO.setLiableMasterName(distributeDTO.getMasterName());
            orderChangeRecordService.updateCancelLiableMasterRecord(cancelLiableMasterDTO);
        } /*else {
            // 如果是返修单，责任工程师和取消责任工程师为源单的工程师
            if (NumberUtil.isNotNullOrZero(dbOrderWork.getOriginalId())) {
                OrderWork rework = orderWorkService.findOrderWorkByKey(dbOrderWork.getOriginalId(), dbOrderWork.getOriginalId());
                ChangeLiableMasterDTO changeLiableMasterDTO = new ChangeLiableMasterDTO();
                changeLiableMasterDTO.setOrderId(dbOrderWork.getOrderId());
                changeLiableMasterDTO.setLiableMasterId(rework.getMasterId());
                changeLiableMasterDTO.setLiableMasterName(rework.getMasterName());
                changeLiableMasterDTO.setCancelLiableMasterId(rework.getMasterId());
                changeLiableMasterDTO.setCancelLiableMasterName(rework.getMasterName());
                changeLiableMasterDTO.setOperator(distributeDTO.getOperator());
                orderChangeRecordService.updateCancelLiableAndLiableMasterRecord(changeLiableMasterDTO);
            }
        }*/

        // 保存改派缘由
        if (Objects.nonNull(distributeDTO.getDistributeReasonId())) {
            OrderRemarkDTO orderRemarkDTO = BeanMapper.map(distributeDTO, OrderRemarkDTO.class);
            orderRemarkDTO.setOrderId(distributeDTO.getOrderId());
            orderRemarkDTO.setWorkId(distributeDTO.getWorkId());
            orderRemarkDTO.setContent(distributeDTO.getDistributeReason());
            OrderRemarkDetailDTO orderRemarkDetailDTO = new OrderRemarkDetailDTO();
            orderRemarkDetailDTO.setMapId(distributeDTO.getDistributeReasonId());
            orderRemarkDetailDTO.setMapName(distributeDTO.getDistributeReason());
            orderRemarkDTO.setDetailDTOList(Arrays.asList(orderRemarkDetailDTO));
            orderRemarkBService.insertOrderRemark(orderRemarkDTO, OrderConsts.ORDER_REMARK_TYPE_REDISTRIBUTE);
        }

        // 重置原工程师工单列表版本
        if (!NumberUtil.isNullOrZero(oldMasterId)) {
            //engineerTouchModifyRemoteService.saveEngineerWorkVersion(oldMasterId, null);
            mqProviderService.sendEngineerWorkVersion(oldMasterId, null);
        }

        // 重置新工程师工单列表版本
        //engineerTouchModifyRemoteService.saveEngineerWorkVersion(distributeDTO.getMasterId(), null);
        mqProviderService.sendEngineerWorkVersion((distributeDTO.getMasterId()), null);

        // 重置产品修改次数
        orderWorkModifyProductBService.resetUpdateProductCount(distributeDTO.getWorkId());

        // 已派单的，撤回重新操作,重置报价及优惠信息
        if (cleanOrderData) {
            zsOrderWorkBService.resetQuotationInfo(dbOrderWork);
        }

        //发送队列消息到erp
        this.syncInfoToERP(dbOrderWork);

        // 发送派单消息
        Map<String, Object> params = Maps.newHashMap();
        List<OrderProduct> orderProducts = orderProductService.listOrderProductByOrderId(dbOrderWork.getOrderId());
        String categOneName = "";
        if (CollectionUtil.isNotNullOrEmpty(orderProducts)) {
            categOneName = orderProducts.get(0).getCategOneName();
        }
        params.put("category_product_name", dbOrderWork.getShowServCategName() + "-" + categOneName);
        params.put("order_id", String.valueOf(dbOrderWork.getOrderId()));
        params.put("work_id", String.valueOf(dbOrderWork.getWorkId()));
        params.put("biz_type", String.valueOf(dbOrderWork.getBizType()));

        // 优质订单判断
        // params.put("high_quality", this.isHighQualityOrder(orderWork.getOrderId()) ? "2" : "1");
        params.put("high_quality", "1");

        // 高等级工程师, 去掉高等级工程师的设置，谢文兵 2022.09.27
        // params.put("high_level_engineer", this.isHighLevelEngineer(distributeDTO.getMasterId(), dbOrderWork.getServProductGroupId(),dbOrderWork.getCityId()) ? "2" : "1");
        params.put("high_level_engineer","1");

                // 获取轮播图片
        OrderWork tipsOrderWork = BeanMapper.map(dbOrderWork, OrderWork.class);
        tipsOrderWork.setMasterId(distributeDTO.getMasterId());
        String newTipSrc = masterNoticeHistoryBService.getNewTipSrc(tipsOrderWork);
        params.put("new_tip_src",newTipSrc);

        messageSendAppService.pushAppMessageInfo(MessageRuleIdConsts.PUSH_MSG_RULEID_DISTRIBUTE, JSON.toJSONString(params), dbOrderWork);

        // 消息补偿
        // messageSendAppService.pushAppMessageInfo(MessageConsts.PUSH_MSG_RULEID_DISTRIBUTE_COMPENSATE, JSON.toJSONString(params), dbOrderWork);

        // 不在一个原子操作内，先锁再释放
        // 派单重新锁定库存
        LockStockDTO lockStockDTO = LockStockDTO.builder()
                .orderId(dbOrderWork.getOrderId())
                .workId(dbOrderWork.getWorkId())
                .masterId(distributeDTO.getMasterId())
                .isDistributeLockStock(true)
                .isExcludeThisOrder(true)
                .build();
        orderStockBService.takeUpStock(lockStockDTO);

        // 释放原工程师库存
        if (cleanOrderData) {
            ReleaseStockDTO releaseStockDTO = new ReleaseStockDTO();
            releaseStockDTO.setOrderId(dbOrderWork.getOrderId());
            releaseStockDTO.setWorkId(dbOrderWork.getWorkId());
            releaseStockDTO.setMasterId(originalMasterId);
            releaseStockDTO.setCityId(dbOrderWork.getCityId());
            orderStockBService.releaseStock(releaseStockDTO);
        }

        return true;
    }

    /**
     * 处理关联多师傅（学徒）
     *
     * @param distributeDTO
     * @param dbOrderWork
     */
    private void processRelateMultiMaster(OrderDistributeDTO distributeDTO, OrderWork dbOrderWork, ForeignEngineerBasicInfoDRO masterBasicInfoDRO) throws OmsBaseException {

        // 1 查询旧工程师关联学徒

        List<Integer> oldApprenticeIdList = null;
        List<OrderMaster> oldOrderMasterList = null;

        do {
            if (dbOrderWork.getMasterId() == null || dbOrderWork.getMasterId() == 0) {
                break;
            }

            List<ForeignEngineerDetailInfoDRO> apprenticeList = this.listApprenticeByMasterId(dbOrderWork.getMasterId(), dbOrderWork.getManageCompanyId(), dbOrderWork.getCityId());
            if (CollectionUtils.isEmpty(apprenticeList)) {
                break;
            }

            // 工程师关联学徒ID列表
            oldApprenticeIdList = Lists.newArrayListWithCapacity(apprenticeList.size());
            for (ForeignEngineerDetailInfoDRO baseEngineerDRO : apprenticeList) {
                oldApprenticeIdList.add(baseEngineerDRO.getEngineerId());
            }

            // 查询工单现在的工程师关联学徒
            if (CollectionUtils.isNotEmpty(oldApprenticeIdList)) {
                oldOrderMasterList = orderMasterService.listMasterByMasterIdList(dbOrderWork.getOrderId(), dbOrderWork.getWorkId(), oldApprenticeIdList);
            }
        } while (false);

        // 2 删除旧关联学徒

        // logger.info("oldApprenticeIdList：" + oldApprenticeIdList);
        if (CollectionUtils.isNotEmpty(oldApprenticeIdList)) {
            orderMasterService.deleteMasterByMasterIdList(dbOrderWork.getOrderId(), dbOrderWork.getWorkId(), OrderConsts.ORDER_MASTER_TYPE_SLAVE, oldApprenticeIdList);
        }

        // 3 查询新工程师关联学徒

        List<OrderMaster> newOrderMasterList = null;

        do {
            // 服务公司 id
            Integer manageCompanyId = dbOrderWork.getManageCompanyId();
            if (manageCompanyId == null || manageCompanyId == 0) {
                if (masterBasicInfoDRO != null) {
                    manageCompanyId = masterBasicInfoDRO.getSpCompanyId();
                }
            }

            List<ForeignEngineerDetailInfoDRO> apprenticeList = this.listApprenticeByMasterId(distributeDTO.getMasterId(), manageCompanyId, dbOrderWork.getCityId());
            if (CollectionUtils.isEmpty(apprenticeList)) {
                break;
            }

            // 需要新增的学徒列表(排除掉已经在工单里面的)
            List<ForeignEngineerDetailInfoDRO> newApprenticeList = null;

            // 排除现在已经在工单里面的工程师
            List<OrderMaster> curOrderMasterList = orderMasterService.listMasterByWorkId(dbOrderWork.getOrderId(), dbOrderWork.getWorkId());
            //logger.info("curOrderMasterList：" + curOrderMasterList);
            if (CollectionUtils.isNotEmpty(curOrderMasterList)) {
                // 将工程师id转换为Set
                Set<Integer> curMasterIdList = curOrderMasterList.stream().map(OrderMaster::getMasterId).collect(Collectors.toSet());
                newApprenticeList = Lists.newArrayListWithCapacity(apprenticeList.size());

                for (ForeignEngineerDetailInfoDRO baseEngineerDRO : apprenticeList) {
                    // 将在不在现工单里面的工程师加入列表
                    if (!curMasterIdList.contains(baseEngineerDRO.getEngineerId())) {
                        newApprenticeList.add(baseEngineerDRO);
                    }
                }
            } else {
                newApprenticeList = apprenticeList;
            }

            if (CollectionUtils.isEmpty(newApprenticeList)) {
                break;
            }

            // 生成新的需要保存的学徒工程师列表
            newOrderMasterList = Lists.newArrayListWithCapacity(newApprenticeList.size());
            Date now = DateUtil.getNow();

            for (ForeignEngineerDetailInfoDRO baseEngineerDRO : newApprenticeList) {
                OrderMaster orderMaster = new OrderMaster();
                orderMaster.setMasterId(baseEngineerDRO.getEngineerId());
                orderMaster.setMasterName(baseEngineerDRO.getRealName());
                orderMaster.setMasterPhone(baseEngineerDRO.getMobile());
                orderMaster.setOrderId(dbOrderWork.getOrderId());
                orderMaster.setWorkId(dbOrderWork.getWorkId());
                orderMaster.setType(OrderConsts.ORDER_MASTER_TYPE_SLAVE);
                orderMaster.setCreateTime(now);
                orderMaster.setStarLevel(GlobalConsts.NONE);
                newOrderMasterList.add(orderMaster);
            }

        } while (false);

        // 4 添加新关联学徒

        // logger.info("newOrderMasterList：" + newOrderMasterList);
        orderMasterBService.insertAll(newOrderMasterList);

        // 5 拼接日志文本(删除学徒多工程师：xx、xx；添加学徒工程师：xx、xx)

        StringBuilder sb = null;

        // 删除学徒多工程师文案
        if (CollectionUtils.isNotEmpty(oldOrderMasterList)) {
            sb = new StringBuilder("删除学徒多工程师：");

            for (int i = 0; i < oldOrderMasterList.size(); i++) {
                OrderMaster orderMaster = oldOrderMasterList.get(i);

                if (i > 0) {
                    sb.append("、");
                }

                sb.append(orderMaster.getMasterName());
            }
        }

        // 添加学徒工程师文案供日志拦截器用
        if (CollectionUtils.isNotEmpty(newOrderMasterList)) {
            if (sb == null) {
                sb = new StringBuilder();
            } else {
                sb.append("；");
            }

            sb.append("；添加学徒工程师：");

            for (int i = 0; i < newOrderMasterList.size(); i++) {
                OrderMaster orderMaster = newOrderMasterList.get(i);

                if (i > 0) {
                    sb.append("、");
                }

                sb.append(orderMaster.getMasterName());
            }
        }

        if (sb != null) {
            distributeDTO.setRelateMultiMasterText(sb.toString());
        }
    }

    // 通过工程师ID调用dubbo查询学徒列表
    private List<ForeignEngineerDetailInfoDRO> listApprenticeByMasterId(Integer masterId, Integer manageCompanyId, Integer cityId) {
        logger.info("listApprenticeByMasterId#listEngineerByMasterId 入参 [{}]",masterId);
        ResponseDTO<List<ForeignEngineerDetailInfoDRO>> responseDTO = engineerListRemoteService.listEngineerByTeacherId(masterId);
        logger.info("listApprenticeByMasterId#listEngineerByMasterId 出参 [{}]",JSON.toJSONString(responseDTO));

        if (!responseDTO.isSuccess() || responseDTO.getData() == null) {
            return Lists.newArrayListWithCapacity(0);
        }

        return responseDTO.getData();
    }

    /**
     * 保存工程师进行中的工单
     *
     * @param orderWork
     * @param status
     */
    private void saveMasterWorking(OrderWork orderWork, Integer status, Integer servItemType, Integer finalPrice) {
        MasterWorking masterWorking = BeanMapper.map(orderWork, MasterWorking.class);

        OrderDetail orderDetail = orderDetailService.findOrderDetailByKey(orderWork.getOrderId());
        masterWorking.setAddress(String.format("%s%s%s", StringUtils.defaultString(orderDetail.getCountyName()), StringUtils.defaultString(orderDetail.getStreet()), StringUtils.defaultString(orderDetail.getAddress())));
        masterWorking.setLatitude(orderDetail.getLatitude());
        masterWorking.setLongitude(orderDetail.getLongitude());
        masterWorking.setProductInfo(orderDetail.getProductInfo());
        masterWorking.setServCategId(orderDetail.getServCategId());
        masterWorking.setServCategName(orderDetail.getServCategName());
        masterWorking.setStatus(status);
        masterWorking.setChannelName(orderWork.getChannelAnotherName());
        masterWorking.setChannelId(orderWork.getChannelId());
        masterWorking.setOuterId(orderWork.getOuterId());
        masterWorking.setServItemType(servItemType);
        masterWorking.setFinalPrice(finalPrice);
        if (Objects.equals(orderWork.getRefundReviewStatus(), OrderConsts.REVIEW_STATUS_DOING)) {
            masterWorking.setWaitCancel(GlobalConsts.YES);
        }

        OrderExtend orderExtend = orderExtendService.findOrderExtendByOrderId(orderWork.getOrderId());
        if (Objects.nonNull(orderExtend)) {
            masterWorking.setAllowRefund(orderExtend.getAllowRefund());
        }

        List<OrderProduct> orderProducts = orderProductService.listOrderProductByOrderId(orderWork.getOrderId());
        if (CollectionUtil.isNotNullOrEmpty(orderProducts)) {
            masterWorking.setCategOneName(orderProducts.get(0).getCategOneName());
        }
        masterWorkingService.saveMasterWorking(masterWorking);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @OrderWorkCasOperate(type = OrderConsts.ORDER_OP_TYPE_MULTI_MASTER)
    @ZsNormalOrderWorkLog(type = OrderLogConsts.ORDER_LOG_TYPE_MULTI_MASTER, beforeProceed = false, handleLog = false)
    public void saveMultiMaster(MultiMasterDTO multiMasterDTO) throws OmsBaseException {
        this.processMultiMaster(multiMasterDTO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveMultiMasterNoLog(MultiMasterDTO multiMasterDTO) throws OmsBaseException {
        this.processMultiMaster(multiMasterDTO);
    }

    private void processMultiMaster(MultiMasterDTO multiMasterDTO) throws OmsBaseException {
        Date now = DateUtil.getNow();
        List<Integer> newMasterIdList = Optional.ofNullable(multiMasterDTO.getMasterList()).orElse(Lists.newArrayListWithCapacity(0));

        // 查询旧从工程师数据，筛选已删除的工程师
        List<OrderMaster> dbOrderMasterList = orderMasterService.listMasterByWorkId(multiMasterDTO.getOrderId(), multiMasterDTO.getWorkId(), OrderConsts.ORDER_MASTER_TYPE_SLAVE);

        // 判断多工程师是否变更
        boolean isChanged = multiMasterDTO.getMasterList().size() != dbOrderMasterList.size() || dbOrderMasterList.stream().anyMatch(item -> !newMasterIdList.contains(item.getMasterId()));
        if (!isChanged) {
            return;
        }

        OrderWork orderWork = orderWorkService.findOrderWorkByKey(multiMasterDTO.getOrderId(), multiMasterDTO.getWorkId());
        // 校验师傅库存是否可用 （新单、返修单） TODO wyc 批量占用-需要杨宽提供新的接口
//        if (Objects.equals(orderWork.getType(), OrderConsts.ORDER_TYPE_NEW) || Objects.equals(orderWork.getType(), OrderConsts.ORDER_TYPE_REWORK)) {
//            boolean isStockOverdue = orderStockBService.isStockOverdue(multiMasterDTO.getOrderId(), multiMasterDTO.getWorkId());
//            // 库存未过期 多工程师占用库存
//            if (!isStockOverdue) {
//                for (Integer masterId : newMasterIdList) {
//                    LockStockDTO lockStockDTO = LockStockDTO.builder()
//                            .orderId(orderWork.getOrderId())
//                            .workId(orderWork.getWorkId())
//                            .masterId(masterId)
//                            .build();
//                    orderStockBService.takeUpStock(lockStockDTO);
//                }
//            }
//        }

        // 删除从工程师
        if (!dbOrderMasterList.isEmpty()) {
            orderMasterService.deleteMaster(multiMasterDTO.getOrderId(), multiMasterDTO.getWorkId(), OrderConsts.ORDER_MASTER_TYPE_SLAVE);
        }

        List<OrderMaster> newOrderMasterList = Lists.newArrayList();
        for (Integer masterId : newMasterIdList) {
            OrderMaster orderMaster = new OrderMaster();
            orderMaster.setMasterId(masterId);
            orderMaster.setOrderId(multiMasterDTO.getOrderId());
            orderMaster.setWorkId(multiMasterDTO.getWorkId());
            orderMaster.setType(OrderConsts.ORDER_MASTER_TYPE_SLAVE);
            orderMaster.setCreater(multiMasterDTO.getOperator());
            orderMaster.setCreateTime(now);
            orderMaster.setStarLevel(GlobalConsts.NONE);
            newOrderMasterList.add(orderMaster);
        }

        // 批量保存
        orderMasterBService.insertAll(newOrderMasterList);

        // 更新工单多工程师状态
        OrderWork updateOrderWork = new OrderWork();
        updateOrderWork.setOrderId(multiMasterDTO.getOrderId());
        updateOrderWork.setWorkId(multiMasterDTO.getWorkId());
        updateOrderWork.setMultiMaster(multiMasterDTO.getMasterList().isEmpty() ? GlobalConsts.NO : GlobalConsts.YES);
        updateOrderWork.setUpdater(multiMasterDTO.getOperator());
        updateOrderWork.setUpdateTime(now);
        updateOrderWork.setCurrentRemark(multiMasterDTO.getOperatorRemark());
        orderWorkService.saveMultiMaster(updateOrderWork);

        List<Integer> dbMasterIdList = Lists.newArrayListWithCapacity(dbOrderMasterList.size());
        dbOrderMasterList.forEach(item -> dbMasterIdList.add(item.getMasterId()));
        // 获取删除的工程师数据
        List<Integer> removedMasterList = dbMasterIdList.stream().filter(masterId -> !multiMasterDTO.getMasterList().contains(masterId)).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(removedMasterList)) {
            // 退还配件，多工程师只有内报配件
            orderPartBService.clearInOrderPartByMasterIds(multiMasterDTO.getOrderId(), removedMasterList, multiMasterDTO.getOperatorId(), multiMasterDTO.getOperator());
        }

        // 操作日志
        List<String> masterList = dbOrderMasterList.stream().map(OrderMaster::getMasterName).collect(Collectors.toList());
        List<String> newMasterList = newOrderMasterList.stream().map(OrderMaster::getMasterName).collect(Collectors.toList());
        multiMasterDTO.setOperatorLogRemark(String.format("%s->%s", StringUtils.join(masterList, "；"), StringUtils.join(newMasterList, "；")));

    }


    @Override
    public void updateConfirmToInputStatus(OrderUpdateStatusDTO orderUpdateStatusDTO) {
        Date now = DateUtil.getNow();

        // 修改订单状态
//        Order order = new Order();
//        order.setOrderId(orderUpdateStatusDTO.getOrderId());
//        order.setStatus(orderUpdateStatusDTO.getStatus());
//        order.setUpdater(orderUpdateStatusDTO.getOperator());
//        order.setUpdateTime(now);
//        orderService.updateConfirmStatus(order);

        // 修改工单状态
        OrderWork orderWork = new OrderWork();
        orderWork.setOrderId(orderUpdateStatusDTO.getOrderId());
        orderWork.setWorkId(orderUpdateStatusDTO.getWorkId());
        orderWork.setStatus(orderUpdateStatusDTO.getStatus());
        orderWork.setUpdater(orderUpdateStatusDTO.getOperator());
        orderWork.setUpdateTime(now);
        orderWorkService.updateConfirmToInputStatus(orderWork);
    }

    @Override
    public void updateToAssignStatus(OrderUpdateStatusDTO orderUpdateStatusDTO) throws OmsBaseException {
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderUpdateStatusDTO.getOrderId(), orderUpdateStatusDTO.getWorkId());

        // 修改状态到已分单
        this.updateToAssignStatus(orderUpdateStatusDTO, orderWork);

        // 删除进行中工单并清除对应工程师的工单版本号
        boolean deleted = masterWorkingService.deleteMasterWorking(orderUpdateStatusDTO.getWorkId());
        if (deleted && orderWork.getMasterId() != null && orderWork.getMasterId() != 0) {
            mqProviderService.sendEngineerWorkVersion(orderWork.getMasterId(), null);
        }

    }

    @Override
    public void updateAssignBack(OrderUpdateStatusDTO updateStatusDTO) throws OmsBaseException {
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(updateStatusDTO.getOrderId(), updateStatusDTO.getWorkId());

        // 修改状态至分单
        Map<String, Boolean> fields = Maps.newHashMap();
        OrderWork updateOrderWork = processUpdateStatusAndCleanData(updateStatusDTO, orderWork, fields, true, true, true, false);
        orderWorkService.updateAssignBack(updateOrderWork, fields);

        // 删除进行中工单并清除对应工程师的工单版本号
        boolean deleted = masterWorkingService.deleteMasterWorking(updateStatusDTO.getWorkId());
        if (deleted && orderWork.getMasterId() != null && orderWork.getMasterId() != 0) {
            mqProviderService.sendEngineerWorkVersion(orderWork.getMasterId(), null);
        }
    }


    @Transactional(rollbackFor = Exception.class)
    @ZsNormalOrderWorkLog(type = OrderLogConsts.ORDER_LOG_TYPE_UPDATE_CHANNEL)
    @Override
    public void updateChannel(ChannelUpdateDTO channelUpdateDTO) throws OmsBaseException {

        // 处理工单服务项类型相关信息
        Integer newServItemType = this.processServItemTypeInfo(channelUpdateDTO);

        OrderWork orderWork = new OrderWork();
        orderWork.setOrderId(channelUpdateDTO.getOrderId());
        orderWork.setWorkId(channelUpdateDTO.getWorkId());
        orderWork.setChannelId(channelUpdateDTO.getChannelId());
        orderWork.setServItemType(newServItemType);

        // 设置渠道类型
        ResponseDTO<com.zmn.base.channel.common.dro.ChannelDRO> responseDTO = channelListRemoteService.getByChannelId(channelUpdateDTO.getChannelId());
        ChannelDRO channelDRO = responseDTO.getData();
        if (responseDTO.isSuccess() && channelDRO != null) {
            // orderWork.setChannelTypeId(channelDRO.getTypeId());
            orderWork.setChannelName(channelDRO.getName());
            orderWork.setChannelAnotherName(StringUtils.defaultString(channelDRO.getAnotherName(), ""));
            orderWork.setChannelOneId(channelDRO.getPlat());
            orderWork.setChannelTwoId(channelDRO.getParentId());
        }

        orderWork.setOuterId(channelUpdateDTO.getOuterId());
        orderWork.setCurrentRemark(channelUpdateDTO.getOperatorRemark());
        orderWorkService.updateChannel(orderWork);

        OrderWork dbOrderWork = orderWorkService.findOrderWorkByKey(channelUpdateDTO.getOrderId(), channelUpdateDTO.getWorkId());

        // 进行中且派单后的工单，同步到进行中
        if (Objects.equals(dbOrderWork.getResultStatus(), OrderStatusConsts.WORK_RESULT_DOING) &&
                dbOrderWork.getStatus() >= OrderStatusConsts.WORK_STATUS_DISTRIBUTE) {
            masterWorkingService.updateMasterWorkingChannel(orderWork.getWorkId(), orderWork.getChannelId(), orderWork.getChannelAnotherName(), newServItemType);
        }
    }

    @Override
    public void updateCleanOrderAndAmount(Long orderId, Long workId, Integer servCategId, OrderDTO orderDTO) throws OmsBaseException {
        OrderWork orderWork = orderWorkService.findOrderWorkByKeySrcMaster(orderId, workId);
        OrderUpdateStatusDTO orderUpdateStatusDTO = new OrderUpdateStatusDTO();
        orderUpdateStatusDTO.setWorkId(orderWork.getWorkId());
        orderUpdateStatusDTO.setOrderId(orderWork.getOrderId());
        orderUpdateStatusDTO.setStatus(orderWork.getStatus());
        orderUpdateStatusDTO.setServCategId(servCategId);
        orderUpdateStatusDTO.setOperatorId(orderDTO.getOperatorId());
        orderUpdateStatusDTO.setOperator(orderDTO.getOperator());

        Map<String, Boolean> fields = Maps.newHashMap();
        OrderWork updateOrderWork = processUpdateStatusAndCleanData(orderUpdateStatusDTO, orderWork, fields, false, false, false, true);
        orderWorkService.updateToAssignStatus(updateOrderWork, fields);
    }

    /**
     * 修改订单状态，并清空数据，已派单、已领单或已上门状态 -> 已确认
     *
     * @param orderUpdateStatusDTO
     * @param orderWork
     */
    private void updateToAssignStatus(OrderUpdateStatusDTO orderUpdateStatusDTO, OrderWork orderWork) throws OmsBaseException {
        Map<String, Boolean> fields = Maps.newHashMap();
        OrderWork updateOrderWork = processUpdateStatusAndCleanData(orderUpdateStatusDTO, orderWork, fields, true, true, true, false);
        orderWorkService.updateToAssignStatus(updateOrderWork, fields);
    }

    /**
     * 取消多次上门
     *
     * @param orderWork
     */
    private void cancelMultipleVisit(OrderUpdateStatusDTO orderUpdateStatusDTO, OrderWork orderWork) throws OmsBaseException {
        // 如果未上门则全部取消
        List<OrderVisit> orderVisitList = orderVisitService.listByOrderIdAndMasterId(orderWork.getOrderId(), orderWork.getMasterId());

        if (CollectionUtil.isNullOrEmpty(orderVisitList)) {
            return;
        }
        // 只过滤已提交和已出发
        orderVisitList = orderVisitList.stream()
                .filter(e -> Objects.equals(e.getVisitStatus(), OrderVisitStatusConsts.ORDER_VISIT_STATUS_APPLY)
                        || Objects.equals(e.getVisitStatus(), OrderVisitStatusConsts.ORDER_VISIT_STATUS_SET_OUT))
                .collect(Collectors.toList());
        if (CollectionUtil.isNullOrEmpty(orderVisitList)) {
            return;
        }
        OrderMultipleVisitDTO dto = new OrderMultipleVisitDTO();
        dto.setOrderId(orderWork.getOrderId());
        dto.setWorkId(orderWork.getWorkId());

        dto.setOperator(orderUpdateStatusDTO.getOperator());
        dto.setOperatorId(orderUpdateStatusDTO.getOperatorId());
        dto.setOperatorType(orderUpdateStatusDTO.getOperatorType());
        dto.setOperateTime(Optional.ofNullable(orderUpdateStatusDTO.getOperateTime()).orElse(DateUtil.getNow()));
        for (OrderVisit orderVisit : orderVisitList) {
            dto.setVisitId(orderVisit.getVisitId());
            orderWorkMultipleVisitBService.cancelAgainVisit(dto);
        }
    }

    /**
     * 清空订单相关数据和订单状态、金额等数据
     *
     * @param orderUpdateStatusDTO
     * @param orderWork
     * @param fields
     * @return
     */
    private OrderWork processUpdateStatusAndCleanData(OrderUpdateStatusDTO orderUpdateStatusDTO, OrderWork orderWork, Map<String, Boolean> fields, boolean isCleanMaster, boolean isCleanPhoto, boolean isClearVisitUser, boolean isForceClearServiceItemInfo) throws OmsBaseException {

        // 删除工程师
        fields.put("cleanMaster", isCleanMaster);
        if (isCleanMaster) {
            // 1、删除主工程师/多工程师
            orderMasterService.deleteMaster(orderUpdateStatusDTO.getOrderId(), orderUpdateStatusDTO.getWorkId(), null);
            // 取消上门
            this.cancelMultipleVisit(orderUpdateStatusDTO, orderWork);
            // 清空验收信息
            orderWorkAcceptanceService.deleteAcceptanceByOrderId(orderUpdateStatusDTO.getOrderId());
        }

        // 厂商单，删除配件审核数据
        if (Objects.equals(orderWork.getSourceType(), OrderConsts.ORDER_SOURCE_TYPE_FACTORY)) {
            zsOrderFactoryPartBService.deleteAllParts(orderUpdateStatusDTO.getOrderId());
        }

        // 2、清空：配件、贴花照片、其他照片、保修内容
        orderPartBService.clearOrderPart(orderUpdateStatusDTO.getOrderId(), orderUpdateStatusDTO.getOperatorId(),
                orderUpdateStatusDTO.getOperator());
        OrderPartReviewDIO orderPartReviewDIO = new OrderPartReviewDIO();
        orderPartReviewDIO.setReviewStatus(com.zmn.consts.GlobalConsts.NONE);
        orderPartReviewDIO.setWorkId(orderUpdateStatusDTO.getWorkId());
        orderPartReviewDIO.setOperator(orderUpdateStatusDTO.getOperator());
        orderPartReviewDIO.setPartUse(com.zmn.consts.GlobalConsts.NO);
        zsNormalOrderPartBService.modifyOrderPartReview(orderPartReviewDIO);
        // 不是厂商单，不删除配件和物流，厂商单在上边删除了。
        //orderFactoryPartService.deleteByOrderId(orderUpdateStatusDTO.getOrderId());
        //orderFactoryPartPostService.deleteByOrderId(orderUpdateStatusDTO.getOrderId());

        List<OrderAttachment> orderAttachmentList = orderAttachmentService.listAttachmentByOrderId(orderUpdateStatusDTO.getOrderId());

        // 增加条件判断是否保留原拍的照片信息 - add by xiewenbing 2020.01.16
        if (isCleanPhoto) {
            orderExtendService.clearAppliqueSrcAndImageSrcByKey(orderUpdateStatusDTO.getOrderId());
            if (CollectionUtils.isNotEmpty(orderAttachmentList)) {
                List<OrderAttachment> attachments = orderAttachmentList.stream().filter(item -> Objects.equals(item.getType(), OrderAttachmentTypeEnum.CONSTS_THZ)).collect(Collectors.toList());
                for (OrderAttachment attachment : attachments) {
                    orderAttachmentService.deleteByKey(attachment.getAttachmentId());
                }
            }
        }

        // 计价器3.0清除报价流程数据
        if (Objects.equals(orderWork.getServItemType(), OrderConsts.SERVICE_ITEM_TYPE_QUOTATION_THREE)) {
            orderQuotation3ModifyBService.clearQuotationInfo(orderWork.getOrderId(), orderWork.getWorkId(), true);
        }

        orderWarrantyService.deleteByOrderId(orderUpdateStatusDTO.getOrderId());

        OrderWork updateOrderWork = new OrderWork();
        updateOrderWork.setOrderId(orderUpdateStatusDTO.getOrderId());
        updateOrderWork.setWorkId(orderUpdateStatusDTO.getWorkId());
        if (isForceClearServiceItemInfo || !this.checkOrderIsFixedPrice(orderWork)) {
            // 未支付清空 产品扩展 服务项 订单金额 订单收入 工程师收款金额
            orderProductExtendService.deleteByOrderId(orderUpdateStatusDTO.getOrderId());
            orderServiceItemService.deleteByOrderId(orderUpdateStatusDTO.getOrderId());

            // 清空渠道附件(除贴花照片)
            if (CollectionUtils.isNotEmpty(orderAttachmentList)) {
                List<OrderAttachment> attachments = orderAttachmentList.stream().filter(item ->
                        !Objects.equals(item.getType(), OrderAttachmentTypeEnum.CONSTS_THZ)).collect(Collectors.toList());
                for (OrderAttachment attachment : attachments) {
                    orderAttachmentService.deleteByKey(attachment.getAttachmentId());
                }
            }

            fields.put("totalAmount", true);

            // 未支付定金 清空
            boolean isPayDeposit = Objects.equals(orderWork.getDepositStatus(), PayConsts.PAY_STATUS_DONE);
            fields.put("depositAmount", !isPayDeposit);

            // 清空人工优惠
            Integer discountAmount = null;
            if (orderWork.getDiscountAmount() != null) {
/*            List<OrderDiscount> discountList = orderDiscountService.listByOrderIdSrcMaster(orderWork.getOrderId());

            List<Integer> artificial = Arrays.asList(FicoConsts.ORDER_IN_DISCOUNT_CATEG_ARTIFICIAL_OPERATOR, FicoConsts.ORDER_IN_DISCOUNT_CATEG_ARTIFICIAL_MASTER
                    , FicoConsts.ORDER_IN_DISCOUNT_CATEG_CHANNEL);
            discountAmount = discountList.stream()
                    .filter(e -> !artificial.contains(e.getCateg()))
                    .mapToInt(OrderDiscount::getAmount).sum();

            orderDiscountService.deleteByArtificialDiscount(orderWork.getOrderId());*/
            }


            // 计算和更新工单金额
            ReCalcOrderAmountDIO calcOrderAmountDIO = orderAmountCalcBService.getReCalcOrderAmountDIO(orderWork);
            OrderAmountCalcBO orderAmountCalcBO = orderAmountCalcBService.reCalcOrderAmountAndDiscountAmount(TriggerAmountChangeEnum.DELETE_ORDER_AMOUNT, calcOrderAmountDIO, null);
            orderWorkAmountBService.updateAmountAndDiscount(orderAmountCalcBO, orderWork);

            // 人工优惠
            fields.put("discountAmount", NumberUtil.isNullOrZero(discountAmount));

            updateOrderWork.setDiscountAmount(discountAmount);

        }
        updateOrderWork.setStatus(orderUpdateStatusDTO.getStatus());
        updateOrderWork.setUpdater(orderUpdateStatusDTO.getOperator());
        updateOrderWork.setUpdateTime(DateUtil.getNow());

        if (isClearVisitUser && Objects.equals(orderWork.getServItemType(), OrderConsts.SERVICE_ITEM_TYPE_QUOTATION_THREE)) {
            fields.put("clearVisitInfo", true);
        }

        return updateOrderWork;
    }

    @Override
    public void updateProduct(ModifyProductDTO modifyProductDTO, OrderWork orderWork) throws OmsBaseException {

        // 清空内部优惠
        Integer discountAmount = null;
        if (orderWork.getDiscountAmount() != null) {
        /*    List<OrderDiscount> discountList = orderDiscountService.listByOrderId(orderWork.getOrderId());
            discountAmount = discountList.stream().mapToInt(OrderDiscount::getAmount).sum();

            // 内部优惠券优惠
            List<OrderDiscount> coupDiscountList = discountList.stream().filter(e -> Objects.equals(e.getCateg(), FicoConsts.ORDER_IN_DISCOUNT_CATEG_COUPON)).collect(Collectors.toList());

            if (coupDiscountList.size() > 0) {
                OrderDiscount orderDiscount = coupDiscountList.get(0);
                // 判断是否是内部优惠券
                boolean internalCoupon = false;
                Integer sourceId = orderDiscount.getSourceId();
                CoupBatchDIO coupBatchDIO = new CoupBatchDIO();
                coupBatchDIO.setBatchId(sourceId);
                log.debug("#oms#serviceitem 获取优惠券批次类型入参:{}", JSON.toJSONString(coupBatchDIO));
                com.zmn.common.dto.ResponseDTO<CoupBatchDRO> batchDROResponseDTO = coupRemoteService.getCoupontypeByBatchId(coupBatchDIO);
                log.debug("#oms#serviceitem 获取优惠券批次类型出参:{}", JSON.toJSONString(batchDROResponseDTO));
                if (batchDROResponseDTO.getStatusBool() && batchDROResponseDTO.getData() != null && Objects.equals(batchDROResponseDTO.getData().getCouponType(), GlobalConsts.NO)) {
                    internalCoupon = true;
                }

                if (internalCoupon) {
                    discountAmount -= orderDiscount.getAmount();

                    String lastUserCouponCode = JSON.parseObject(orderDiscount.getSourceData()).getString("itemCode");
                    // 先退还给用户
                    if (StringUtil.isNotBlank(lastUserCouponCode)) {
                        // 返还优惠券
                        returnCoupon(orderWork.getOrderId(), orderWork.getUserId());

                        // 删除之前使用的优惠券
                        orderDiscountService.deleteByKey(orderDiscount.getDiscountId());
                    }
                }
            }*/

            // 更新工单优惠金额
            // 删除优惠之后，在processUpdateStatusAndCleanData（）中会重新计算优惠金额
//            WorkAmountDTO workAmountDTO = new WorkAmountDTO();
//            workAmountDTO.setOrderId(orderWork.getOrderId());
//            workAmountDTO.setWorkId(orderWork.getWorkId());
//            workAmountDTO.setAmount(discountAmount);
//            orderWorkAmountBService.updateDiscountAmount(workAmountDTO);
        }

        // 清空相关信息
        OrderUpdateStatusDTO orderUpdateStatusDTO = new OrderUpdateStatusDTO();
        orderUpdateStatusDTO.setWorkId(orderWork.getWorkId());
        orderUpdateStatusDTO.setOrderId(orderWork.getOrderId());
        orderUpdateStatusDTO.setStatus(orderWork.getStatus());
        orderUpdateStatusDTO.setOperatorId(modifyProductDTO.getOperatorId());
        orderUpdateStatusDTO.setOperator(modifyProductDTO.getOperator());

        Map<String, Boolean> fields = Maps.newHashMap();
        OrderWork updateOrderWork = processUpdateStatusAndCleanData(orderUpdateStatusDTO, orderWork, fields, false, false, false, false);
        orderWorkService.updateToAssignStatus(updateOrderWork, fields);
    }

    /*    *//**
     * 退换用户优惠券
     * @param orderId 订单id
     * @param userId 用户id
     *//*
   private void returnCoupon(Long orderId, Long userId) {

        CoupItemDIO coupItemDIO = new CoupItemDIO();
        coupItemDIO.setOrderId(orderId);
        coupItemDIO.setUseUserId(userId);
        coupItemDIO.setStatus(GlobalConsts.YES);
        log.debug("#oms#serviceitem 退还优惠券入参：{}", JSON.toJSONString(coupItemDIO));
        com.zmn.common.dto.ResponseDTO responseDTO = coupRemoteService.updateCoupItemStatus(coupItemDIO);
        log.debug("#oms#serviceitem 退还优惠券出参：{}", JSON.toJSONString(responseDTO));
    }*/

    /**
     * 处理工单服务项类型相关信息
     *
     * @param channelUpdateDTO
     */
    private Integer processServItemTypeInfo(ChannelUpdateDTO channelUpdateDTO) throws OmsBaseException {
        // 获取工单
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(channelUpdateDTO.getOrderId(), channelUpdateDTO.getWorkId());

        // 新旧工单类型
        Integer oldServItemType = orderWork.getServItemType();

        orderWork.setChannelId(channelUpdateDTO.getChannelId());
        CheckQuotationTypeOrderDTO checkQuotationTypeOrderDTO = BeanMapper.map(orderWork, CheckQuotationTypeOrderDTO.class);
        checkQuotationTypeOrderDTO.setCompanyId(orderWork.getCompanyId());
        checkQuotationTypeOrderDTO.setMasterId(orderWork.getMasterId());
        checkQuotationTypeOrderDTO.setBeforeServItemType(orderWork.getServItemType());
        Integer newServItemType = servItemBService.getServItemType(checkQuotationTypeOrderDTO);

        // 非计价器工单修改渠道
        if (Objects.equals(oldServItemType, newServItemType) && Objects.equals(newServItemType, OrderConsts.SERVICE_ITEM_TYPE_ORDER)) {
            return newServItemType;
        }

        List<OrderProduct> products = orderProductService.listOrderProductByOrderId(orderWork.getOrderId());
        if (Objects.equals(newServItemType, OrderConsts.SERVICE_ITEM_TYPE_FAULT) && CollectionUtils.isNotEmpty(products) && products.get(0).getNumber() > 1) {
            return OrderConsts.SERVICE_ITEM_TYPE_ORDER;
        }

        // 计价器->非计价器 非计价器->计价器 计价器->计价器 需要重新设置服务项/故障项
        // 清空服务项
        if (orderWork.getStatus() < OrderStatusConsts.ORDER_STATUS_COMPLETE) {
            orderServiceItemService.deleteByOrderId(orderWork.getOrderId());
        }

        // 返回新的ServItemType
        return newServItemType;
    }

    private void syncInfoToERP(OrderWork orderWork) {
        if (!Objects.equals(orderWork.getType(), OrderConsts.ORDER_TYPE_NEW)) {
            return;
        }

        OrderDetail orderDetail = orderDetailService.findOrderDetailByKey(orderWork.getOrderId());

        ERPMessageDRO messageDRO = BeanMapper.map(orderWork, ERPMessageDRO.class);
        messageDRO.setProductGroupId(orderWork.getServProductGroupId());
        messageDRO.setPlat(orderWork.getPlatWork());
        messageDRO.setOrderCityId(orderWork.getCityId());
        messageDRO.setSpId(orderWork.getManageCompanyId());

        // 行车距离
        // 获取区县经纬度
        ResponseDTO<AreaDRO> areaDROResponseDTO = areaListRemoteService.getById(orderDetail.getCountyId());
        if (areaDROResponseDTO.isSuccess()) {
            Point point1 = new Point(areaDROResponseDTO.getData().getLongitude(), areaDROResponseDTO.getData().getLatitude());
            Point point2 = new Point(orderDetail.getLongitude(), orderDetail.getLatitude());
            messageDRO.setDistance(Optional.ofNullable(baiduMapBService.getNavigationDistance(point1, point2)).orElse(0));
        }

        // 师傅列表
        List<OrderMaster> masters = orderMasterService.listMasterByWorkId(orderWork.getOrderId(), orderWork.getWorkId());
        List<ERPEngineerDRO> engineerList = masters.stream().map(master -> {
            return new ERPEngineerDRO(master.getMasterId(), master.getMasterName());
        }).collect(Collectors.toList());
        messageDRO.setEngineerList(engineerList);


        String key = String.format("%s_%s_%s", "orderwork_distribute_sync_info", DateUtil.getNowTimestamp(), String.valueOf(orderWork.getWorkId()));
        String content = JSONObject.toJSONString(messageDRO);

        logger.info("#distribute 派单同步相关信息至ERP：key:{} content:{}", key, content);

        zmnMQSender.send(MessageQueueTopicConstant.ZMN_TOPIC_ERP, MQ_CONFIG_SNAPSHOT_DISTRIBUTE_TAG, key, content);
    }

    private boolean checkOrderIsFixedPrice(OrderWork orderWork) {
        ProductPriceQuery productPriceQuery = new ProductPriceQuery();
        productPriceQuery.setBizType(orderWork.getBizType());
        productPriceQuery.setBrandId(orderWork.getProductBrandId());
        productPriceQuery.setChannelId(orderWork.getChannelId());
        productPriceQuery.setCityId(orderWork.getCityId());
        productPriceQuery.setProductIdList(Lists.newArrayList(orderWork.getShowProductId()));
        productPriceQuery.setShowType(CommonConsts.PRODUCT_SHOW_TYPE_FRONT);
        log.info("获取产品价格信息 入参：{}", JSON.toJSONString(productPriceQuery));
        ResponseDTO<List<ProductPriceDRO>> responseDTO = productPriceRemoteService.listProductPriceByQuery(productPriceQuery);
        log.info("获取产品价格信息 出参：{}", JSON.toJSONString(responseDTO));
        if (responseDTO.isSuccess() && CollectionUtils.isNotEmpty(responseDTO.getData())) {
            ProductPriceDRO priceDRO = responseDTO.getData().get(0);
            if (Objects.equals(priceDRO.getItemStandard(), GlobalConsts.YES)
                    && NumberUtil.isNotNullOrZero(priceDRO.getPrice())) {
                return true;
            }
        }
        return false;
    }

    /**
     * 优质订单
     * @param orderId
     * @return
     */
    private boolean isHighQualityOrder(Long orderId) {

        if (NumberUtil.isNullOrZero(orderId)) {
            return false;
        }

        Integer count = orderTagService.countOrderTagByOrderIdAndTagId(orderId, OrderTagConsts.TAG_ID_HIGH_QUALITY);

        return count > 0 ? true : false;
    }

    /**
     * 高等级工程师
     * @param masterId
     * @param productGroupId
     * @param cityId
     * @return
     */
    /*  去掉高等级工程师的设置，谢文兵 2022.09.27
    private boolean isHighLevelEngineer(Integer masterId, Integer productGroupId, Integer cityId) {

        // 参数判断
        if (NumberUtil.isNullOrZero(masterId) || NumberUtil.isNullOrZero(productGroupId) || NumberUtil.isNullOrZero(cityId)) {
            return false;
        }

        try {
            EngineerProductGroupCompositeScoreForDispatchOrderDIO scoreForDispatchOrderDIO = new EngineerProductGroupCompositeScoreForDispatchOrderDIO();
            List<Integer> productGroupIds = new ArrayList<>(1);
            List<Integer> engineerIds = new ArrayList<>(1);

            productGroupIds.add(productGroupId);
            engineerIds.add(masterId);

            scoreForDispatchOrderDIO.setCityId(cityId);
            scoreForDispatchOrderDIO.setProductGroupIds(productGroupIds);
            scoreForDispatchOrderDIO.setEngineerIds(engineerIds);

            ResponseDTO<List<EngineerProductGroupCompositeScoreForDispatchOrderDRO>> responseScoreDTO =
                    compositeServeScoreForOmsListRemoteService.getEngineerCompositeScore(scoreForDispatchOrderDIO);
            log.info("#CompositeServeScoreForOmsListRemoteService#getEngineerCompositeScore 入参:[{}], 出参：[{}]", JSON.toJSONString(scoreForDispatchOrderDIO),JSON.toJSONString(responseScoreDTO));

            if (!responseScoreDTO.isSuccess() || CollectionUtil.isNotNullOrEmpty(responseScoreDTO.getData())) {
                return false;
            }

            EngineerProductGroupCompositeScoreForDispatchOrderDRO scoreDro = responseScoreDTO.getData().get(0);
            if (Objects.isNull(scoreDro)) {
                return false;
            }

            return Objects.equals(scoreDro.getHighGradeFlag(), GlobalConsts.YES) ? true : false;
        } catch (Exception e) {

            log.info("[{}]判断高等级工程师异常，[{}]", masterId, e.getMessage());
            return false;
        }
    }
    */
}
